home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 23 / CU Amiga - Super CD-ROM 23 (June 1998).iso / CreatingGames / GameCreators / TADS / TADS.doc < prev    next >
Encoding:
Text File  |  1996-11-22  |  56.9 KB  |  1,464 lines

  1.  
  2.  
  3.  
  4.  
  5.          TADS: The Text Adventure Development System
  6.         Software for implementing text adventure games
  7.             by Michael J. Roberts
  8.  
  9.  
  10.  
  11.  
  12.  
  13.  
  14.             Overview Documentation
  15.  
  16.  
  17.  
  18.  
  19.         Copyright (c) 1992, 1996 by Michael J. Roberts.
  20.              All Rights Reserved.
  21.  
  22.  
  23.  
  24.  
  25.  
  26.  
  27.  
  28.  
  29.  
  30. ------------------------------------------------------------------------------
  31. Introduction
  32.  
  33. This is a brief overview of TADS, a program that makes it easier to
  34. write your own text adventure games.  TADS is offered as freeeware,
  35. which means that you use the software without charge.
  36.  
  37. This is a summary of the information in the full TADS Author's Manual,
  38. which is also freely available.  We prepared this information to provide
  39. a quick introduction to TADS.
  40.  
  41.  
  42. ------------------------------------------------------------------------------
  43. Ditch Day Drifter
  44.  
  45. We've included a large sample game, Ditch Day Drifter, with TADS.
  46. The source for the game is in the file DITCH.T.  We included Ditch Day
  47. Drifter as a sample of what TADS can do, and to help you see how you
  48. can go about writing your own game with TADS.  After reading through
  49. this description of TADS, you may find it helpful to look at DITCH.T
  50. to see more examples of how to write TADS code.
  51.  
  52. If you want to play Ditch Day Drifter, you need to compile it first.
  53. On MS-DOS machines, go to the TADS directory and type this:
  54.  
  55.    tc ditch
  56.  
  57. The "tc" command runs the TADS Compiler, which converts the game
  58. source file into a binary executable format.  Run the game with
  59. this command:
  60.  
  61.    tr ditch
  62.  
  63.  
  64. On Macintosh systems, start the compiler by double-clicking on the
  65. application named "TADS Compiler".  The compiler will display a dialog
  66. box with several parameters.  Click on the "Select" button next to the
  67. "Filename" box, then select the file DITCH.T using the normal file
  68. selector dialog that appears.  Then, click on the "Compile" button.
  69. When the compiler finishes, click on the "Quit" button.  Now you
  70. can run the game either by double-clicking on the new document
  71. DITCH.GAM, or by double-clicking on the application "TADS Run-Time",
  72. then selecting DITCH.GAM from the file selector dialog.
  73.  
  74.  
  75.  
  76. ------------------------------------------------------------------------------
  77. What is TADS?
  78.  
  79. TADS is a tool that makes it easier to write text adventure games.
  80. The system consists of a compiler, which reads source code written
  81. in the TADS language, checks it for errors, and converts it to an
  82. internal representation; and a run-time system, which reads commands
  83. typed by the player, and controls the interaction between the player
  84. and your game program.
  85.  
  86. It's easier to write an adventure using TADS than with a general
  87. purpose language for several reasons.
  88.  
  89.    - The TADS language is specially designed for text adventure
  90.      games, so the things you do most frequently in programming
  91.      an adventure are easy to do.
  92.  
  93.    - The run-time system provides an excellent player command
  94.      parser -- you don't need to worry about parsing player
  95.      commands at all.
  96.  
  97.    - All of the work of saving and restoring games, undoing
  98.      commands, controlling the on-screen display, and many
  99.      other low-level tasks, is done automatically by the system.
  100.  
  101.    - TADS includes a large set of common adventure objects,
  102.      implemented using the TADS language.  You can use these
  103.      objects as they are, or make your own customizations.
  104.  
  105.    - Games written with TADS are instantly portable to every
  106.      system on which the TADS run-time system is available --
  107.      you don't even need to recompile your game!
  108.  
  109.  
  110.  
  111. ------------------------------------------------------------------------------
  112. Writing games with TADS
  113.  
  114. To write a game with TADS, you start off by writing your game's
  115. source file with a text editor; you can use any editor that can
  116. produce a plain text file.  Once you've written your source file,
  117. you compile it using the TADS compiler.  If the game had no errors,
  118. you can run the game using the TADS run-time system.  As you write
  119. your game, you'll probably write a little, compile it, try it out,
  120. then go back and add more, compile and try that, and so on.
  121.  
  122.  
  123.  
  124. ------------------------------------------------------------------------------
  125. Getting Started - A Sample Game
  126.  
  127. To help you get started writing your own games with TADS, we'll go
  128. through the implementation of a sample game.  This example is similar
  129. to the one used in chapter one of the TADS Author's Manual.
  130.  
  131. We'll start with about the simplest game possible:  two rooms, and
  132. no items.  We could start with only one room, but then there wouldn't
  133. be anything to do while playing the game; with two rooms, at least
  134. the player can move between the rooms.
  135.  
  136. If you want to try running this game, create a file containing the
  137. program text shown below using your text editor or word processor.
  138. The TADS compiler will accept an ASCII file saved by any text editor.
  139. If you're using a word processor, you may have to choose a special
  140. option to save the file as plain text, without any formatting codes;
  141. refer to your word processor's documentation for details.
  142.  
  143. Note that the lines of equal signs are just borders to show where the
  144. example starts and ends; use only the part between the lines of equal
  145. signs when creating the file.
  146.  
  147. ==============================================================================
  148. /* This is a comment, just like in C */
  149. #include <adv.t>              /* read basic adventure game definitions file */
  150. #include <std.t>                   /* read starting standard functions file */
  151.  
  152. startroom: room                      /* the game always starts in startroom */
  153.    sdesc = "Outside cave"              /* the Short DESCription of the room */
  154.    ldesc = "You're standing in the bright sunlight just
  155.             outside of a large, dark, forboding cave, which
  156.             lies to the north."
  157.    north = cave                 /* the room called "cave" lies to the north */
  158. ;
  159.  
  160. cave: room
  161.    sdesc = "Cave"
  162.    ldesc = "You're inside a dark and musty cave.  Sunlight
  163.             pours in from a passage to the south."
  164.    south = startroom
  165. ;
  166. ==============================================================================
  167.  
  168. To run this example, all you have to do is compile it with TC, the TADS
  169. Compiler, then run it with TR, the TADS Run-time system.  If you named
  170. your sample program file "mygame.t", on most operating systems you can
  171. compile it with this command:
  172.  
  173.    tc mygame
  174.  
  175. and you can run it with this command:
  176.  
  177.    tr mygame
  178.  
  179. Let's look at the sample program line by line.
  180.  
  181. The first line is a #include command.  This command inserts another
  182. source file into your program.  The file "adv.t" (included with the
  183. TADS package) is a set of basic definitions that can be used by most
  184. adventure games.  By including adv.t in your game, you don't need to
  185. worry about defining words such as "the", a large set of verbs (such
  186. as "take", "north", and other common verbs), and many "object classes"
  187. (described later).
  188.  
  189. The next line includes the file "std.t" (which is also included with
  190. the TADS package), which contains additional definitions.  The reason
  191. for placing some definitions in the separate file std.t is that you
  192. will almost always want to change most of the definitions in std.t in
  193. a finished game, whereas the definitions in adv.t can be used unchanged
  194. by many games.  (Even though most finished games will customize the
  195. definitions in std.t, the definitions are good enough to get us started
  196. with this sample game.)
  197.  
  198. The next line says "startroom: room".  This tells the compiler that
  199. you're defining a room named "startroom".  A room is nothing special
  200. to TADS, but adv.t, which we previously included, defines what a room
  201. is.  A room is one of the object classes that we mentioned earlier.
  202.  
  203. The next line defines the "sdesc" for this room.  The sdesc is a
  204. short description; for a room, it is displayed whenever a player
  205. enters the room.  The next line is the "ldesc", or long description;
  206. it is displayed when the player enters the room for the first time,
  207. or asks for the full description with the "look" command.  Finally,
  208. the "north" definition says that another room, called "cave", is
  209. reached when the player types "north" while in startroom.
  210.  
  211. Now let's add a few items that can be manipulated by the player.
  212. We'll add a solid gold skull, and a pedestal for it to sit on.
  213. Add these definitions at the end of the source you've already
  214. created.
  215.  
  216. ==============================================================================
  217. pedestal: surface, fixeditem
  218.    sdesc = "pedestal"
  219.    noun = 'pedestal'
  220.    location = cave
  221. ;
  222.  
  223. goldSkull: item
  224.    sdesc = "gold skull"
  225.    noun = 'skull' 'head'
  226.    adjective = 'gold'
  227.    location = pedestal
  228. ;
  229. ==============================================================================
  230.  
  231. As with the "room" class, the "surface", "fixeditem", and "item" classes
  232. are not built in to TADS, but are defined in adv.t.  Note that you can
  233. create an object using more than one class; in the example, the pedestal
  234. object is both a surface and a fixeditem.  A surface is an object that
  235. can have other objects placed upon it; a fixeditem is an object that can't
  236. be picked up and carried by the player.  The goldSkull object is simply
  237. an item, which is an object that the player can pick up and carry around.
  238.  
  239. As with a room, the sdesc property gives a short description of the object;
  240. it should simply be the name of the object.  There is no ldesc property
  241. defined for these objects, so they get the default long descriptions
  242. defined by their classes.  The ldesc for an item simply says, for
  243. example, "It looks like an ordinary gold skull"; for a surface, it
  244. lists the objects sitting on the surface.
  245.  
  246. Since these objects can be manipulated by the player, they must be
  247. associated with vocabulary words.  The noun and adjective definitions
  248. specify the words the player can use to refer to the objects.  Note that
  249. the sdesc and ldesc properties are enclosed in double quotes, but the
  250. vocabulary words are enclosed in single quotes.  Note also that a noun
  251. or adjective can have multiple vocabulary words.
  252.  
  253. The objects have another new property as well:  location.  This simply
  254. defines the object that contains the object being defined.  In the case
  255. of the pedestal, its location is the room "cave"; since the goldSkull
  256. is on the pedestal, its location is the object "pedestal".
  257.  
  258. Now let's add another feature to the game:  let's add a trap, so that
  259. the player can't take the gold skull without getting killed.  To do
  260. this, we'll replace the goldSkull definition shown above with the new
  261. definition below.
  262.  
  263. ==============================================================================
  264. goldSkull: item
  265.    sdesc = "gold skull"
  266.    noun = 'skull' 'head'
  267.    adjective = 'gold'
  268.    location = pedestal
  269.    doTake(actor) =
  270.    {
  271.      "As you lift the skull, a volley of poisonous
  272.      arrows is shot from the walls!  You try to
  273.      dodge the arrows, but they take you by surprise!";
  274.      die();
  275.    }
  276. ;
  277. ==============================================================================
  278.  
  279. The definition of doTake (which stands for Direct Object Take) has an
  280. argument specifying the character who is trying to take the object
  281. (since we have no characters besides the player, the actor will be
  282. the player's character, named "Me").  The system calls doTake whenever
  283. the player attempts to take the object.  Note that this definition of
  284. doTake is associated with the object itself; another object could have
  285. a different doTake that does something entirely different.  In this
  286. case, we simply display a message (since the message is enclosed in
  287. double quotes, it is simply displayed when this statement is executed),
  288. then call the "die" function, which is defined in std.t.
  289.  
  290. You might wonder why we've waited until now to define doTake in the
  291. goldSkull object, or you might have just assumed that the system
  292. automatically knows what to do if doTake is not defined for an object.
  293. In fact, all objects do need a doTake definition, and the system has
  294. no default behavior if the definition is missing.  However, since
  295. most objects will have a very similar doTake definition, it would be
  296. extremely tedious to have to type the whole definition for every
  297. normal object.  Instead, we use something called "inheritance": by
  298. defining the goldSkull to be a member of the "item" class, you tell
  299. TADS that the goldSkull object inherits all of the definitions from
  300. the item class, in addition to any definitions it makes on its own.
  301. The item class (in adv.t) has a definition for doTake that is suitable
  302. for most objects.  However, if an object of class "item" has its
  303. own definition of doTake, the one in the object takes precedence --
  304. it "overrides" the default definition from the class.
  305.  
  306. We don't have a very good puzzle at this point, because there's no
  307. way the player can get the gold skull without getting killed.  So,
  308. let's make it possible for the player to get the skull.  We'll assume
  309. that the mechanism that the pedestal uses to set off the poisoned
  310. arrow trap is a weight sensor:  when the pedestal has too little
  311. weight on it, the trap is set off.  So, we'll create a rock that
  312. the player can use to keep the trap from going off:  the player puts
  313. the rock on the pedestal, then can take the skull.  Add the new
  314. definition below to the end of your source file.
  315.  
  316. ==============================================================================
  317. smallRock: item
  318.    sdesc = "small rock"
  319.    noun = 'rock'
  320.    adjective = 'small'
  321.    location = cave
  322. ;
  323. ==============================================================================
  324.  
  325. Now, we'll change the definition of doTake in the goldSkull object.
  326. Replace the old definition of doTake with the one below.
  327.  
  328. ==============================================================================
  329.    doTake(actor) =
  330.    {
  331.       if (self.location <> pedestal or smallRock.location = pedestal)
  332.       {
  333.          pass doTake;
  334.       }
  335.       else
  336.       {
  337.          "As you lift the skull, a volley of poisonous
  338.          arrows is shot from the walls!  You try to dodge
  339.          the arrows, but they take you by surprise!";
  340.          die();
  341.       }
  342.    }
  343. ==============================================================================
  344.  
  345. This new doTake definition first checks to see if the object being taken
  346. (the special object "self", which is the object whose doTake definition
  347. is being executed), in this case, the gold skull, is already off the
  348. pedestal; if it is, we don't want anything to happen, so we "pass"
  349. doTake.  We also pass doTake if the small rock is on the pedestal.  When
  350. we pass doTake, the doTake definition that we inherited from our parent
  351. class (in this case, item) is invoked.  This allows us to override a
  352. definition only under certain special circumstances, but otherwise
  353. use the default behavior.  If the rock isn't on the pedestal, and the
  354. skull is being removed from the pedestal, the poisoned arrows are
  355. released as before.
  356.  
  357. We've included a file named GOLDSKUL.T that includes this sample
  358. game, with the complete puzzle involving the gold skull and the
  359. pedestal.  You can compile and run that file by typing these
  360. commands:
  361.  
  362.    tc goldskul
  363.    tr goldskul
  364.  
  365.  
  366. ------------------------------------------------------------------------------
  367. The TADS Language
  368.  
  369. If you know how to program in a "procedural" language like C or
  370. Pascal, most of the TADS language will probably look very familiar.
  371. However, the overall structure of a TADS program will probably seem
  372. a little strange at first.
  373.  
  374. In particular, you'll probably wonder where the program begins.
  375. The answer is that a TADS game doesn't have a beginning in the same
  376. sense that a C or Pascal program does.
  377.  
  378. A C program, like a program written in any procedural language,
  379. is a sequence of instructions.  The program starts running at
  380. the main() function, and carries out the instructions listed
  381. there in the order they appear.  The program may call subroutines
  382. or iterate through loops along the way, but control flows
  383. essentially sequentially through the program.
  384.  
  385. A TADS program, in contrast, is simply a series of object definitions.
  386. Each definition specifies the behavior of a single object in the game.
  387. An object definition consists of a series of "properties", which are
  388. attributes of the object.  A property can contain some simple
  389. information, such as the name of the object, or its weight, or can
  390. contain programming language code that defines the object's behavior.
  391.  
  392. Obviously, the information you specify in your object definitions
  393. has to be used somehow -- something has to call the program code that
  394. you write.  In TADS, it's the player command parser that does the work
  395. of deciding which properties to use in which objects in response to
  396. the player's commands.
  397.  
  398. Later on, we'll describe in detail how the parser decides which properties
  399. to evaluate.  In order to take full advantage of the power of TADS by
  400. creating your own types of objects, you'll need to understand how the
  401. parser works.  However, one of the advantages of using TADS is that
  402. you can define objects using existing types without having to know
  403. everything about how those types work.  So, we'll start off by showing
  404. you how to create some simple objects that you'll find in almost every
  405. adventure game.
  406.  
  407.  
  408. ------------------------------------------------------------------------------
  409. Creating a Room
  410.  
  411. The first type of object you'll want to create in an adventure game
  412. is a room, which is simply a location in the game.  The attributes of
  413. a room are typically its name, its description, and links to other
  414. rooms.
  415.  
  416. The first thing you'll need to do in defining a room, or any TADS
  417. object, is to choose its object name.  This is not a name that is
  418. ever displayed to or used by the player -- it is a purely internal
  419. name that you use to refer to the object within the TADS program.
  420. It is similar to the name of a variable in C or Pascal.  In TADS,
  421. the name of an object must start with a letter, and can consist of
  422. letters, numbers, and underscores.
  423.  
  424. Here's a sample room definition.
  425.  
  426.    nsCrawl:  room
  427.       sdesc = "North-South Crawl"
  428.       ldesc = "You're in a narrow, low passage connecting
  429.               caves to the north and south.  A cold, damp
  430.               breeze comes from the north."
  431.       north = iceRoom
  432.       south = roundRoom
  433.    ;
  434.  
  435. The first line of the object definition gives the object its name,
  436. "nsCrawl", and specifies the type of the object.  Note that the case
  437. of the letters in the name is significant -- "nsCrawl" is a different
  438. name than "NSCrawl" or "nscrawl".
  439.  
  440. The next line specifies a property of the object -- the sdesc, or
  441. short description.  It says that the property sdesc is the string
  442. "North-South Crawl".  The sdesc is displayed whenever the player
  443. enters the room, and is also used on the status line.
  444.  
  445. In TADS, double-quoted strings are special:  they mean that the
  446. string is to be displayed whenever the property is evaluated.
  447. Double-quoted strings are similar to using a PRINT statement in
  448. other languages.  So, whenever the sdesc property of the nsCrawl
  449. object is evaluated, the string "North-South Crawl" will be displayed
  450. to the player.
  451.  
  452. The next line defines the ldesc, or long description, property.
  453. This is the full description of the room that is displayed when
  454. the player enters the room for the first time, or whenever the player
  455. uses the "look" command to ask for a full description.  Note that
  456. this property's value is a double-quoted string, just like the sdesc,
  457. to indicate that the string is displayed whenever the ldesc is
  458. evaluated.
  459.  
  460. The next two lines specify the directional properties north and south.
  461. These properties are set to refer to other room objects.  They specify
  462. that the player will end up in the room defined by the object
  463. iceRoom by going north, and in roundRoom by going south.  Note that
  464. other directions are not specified -- this simply means that the player
  465. can't go in any other directions.  The other possible direction properties
  466. are east, west, up, down, in, out, ne, se, nw, and sw (the last four
  467. stand for northeast, southeast, northwest, and southwest, respectively).
  468.  
  469. The final line of the room definition is a semicolon, which tells TADS
  470. that the object definition is finished.
  471.  
  472.  
  473. ------------------------------------------------------------------------------
  474. Creating Items
  475.  
  476. In addition to rooms, you'll want to create objects that the player
  477. can pick up and carry around.  These are objects of type "item".
  478. When you define an item, you'll need to specify another set of
  479. properties:  its short and long descriptions (just like rooms),
  480. its location (which says where the object is originally situated),
  481. and vocabulary words that specify how the player can refer to the
  482. object.  Here are a couple of item definitions.
  483.  
  484.    dollar: item
  485.       location = nsCrawl
  486.       sdesc = "one-dollar bill"
  487.       noun = 'dollar' 'bill'
  488.       adjective = 'one' 'one-dollar' '1' 'dollar'
  489.    ;
  490.  
  491.    rope: item
  492.       noun = 'rope'
  493.       sdesc = "rope"
  494.       ldesc = "It's about 50 feet long, and seems quite strong; it's
  495.               probably capable of handling several hundred pounds."
  496.       location = backpack
  497.    ;
  498.  
  499. The first thing to notice here is that vocabulary words are enclosed
  500. in single quotes, not double quotes.  Recall that double-quoted strings
  501. are displayed whenever evaluated; this is obviously not desirable for
  502. vocabulary words.  So, always specify vocabulary words with single quotes.
  503.  
  504. You may also notice that more than one single-quoted string can be
  505. used with a vocabulary property.  This is a unique feature of vocabulary
  506. properties (the vocabulary properties are noun, adjective, plural,
  507. verb, preposition, and article).  When you use more than one word
  508. in a vocabulary property, it simply creates multiple synonyms that can
  509. be used to refer to the object.
  510.  
  511. Note that the properties can be defined in any order.  Note also that
  512. you don't need to specify every property; for example, if the ldesc
  513. property is not specified with an item, a default message ("It looks
  514. like an ordinary one-dollar bill") is displayed.  However, practically
  515. every item will define the properties sdesc, location, and noun.
  516.  
  517. The location property specifies the original location of the object.
  518. In many cases, the location will refer to a room object.  However, it
  519. can also refer to another game item; in these cases, the item should
  520. be a container, as described below.
  521.  
  522.  
  523. ------------------------------------------------------------------------------
  524. Containers
  525.  
  526. You will often want to create items that can contain other items.
  527. To do this, simply create an item of type "container" rather than
  528. "item".  In other respects, a "container" object is the same as
  529. an "item", and you specify the same set of properties.  Here's an
  530. example.
  531.  
  532.    backpack: container
  533.       sdesc = "backpack"
  534.       location = maintenanceRoom
  535.       noun = 'backpack' 'pack' 'bag'
  536.       adjective = 'back'
  537.    ;
  538.  
  539. In addition to container objects, you can create "openable" objects.
  540. These are the same as containers, except that they can be opened and
  541. closed.  When you create a container, there's a new property,
  542. "isopen", that specifies whether the object is open or closed.
  543. If you want the object to be closed initially, set isopen = nil.
  544. Here's an example.
  545.  
  546.    toolbox: openable
  547.       sdesc = "tool box"
  548.       location = maintenanceRoom
  549.       noun = 'toolbox' 'box'
  550.       adjective = 'tool'
  551.       isopen = nil
  552.    ;
  553.  
  554.  
  555. ------------------------------------------------------------------------------
  556. Fixed Items
  557.  
  558. You will frequently want to create items in the game that the player
  559. can't pick up and carry around, but that are permanent features of
  560. a room.  For example, if you create a bedroom, you'll probably want
  561. to have a bed and maybe a dresser in the room.  It doesn't make sense
  562. for the player to be able to carry off the furniture.
  563.  
  564. To create an item that the player can't carry, create an object of
  565. type "fixeditem".  You define fixeditem objects that same way that
  566. you define item objects; the only difference is that fixeditem objects
  567. can't be carried off by the player.
  568.  
  569. Here's an example.
  570.  
  571.    bed: fixeditem
  572.       location = bedroom
  573.       noun = 'bed'
  574.       sdesc = "Bed"
  575.    ;
  576.  
  577.  
  578. ------------------------------------------------------------------------------
  579. Inheritance and ADV.T
  580.  
  581. Up to now, we've been describing the various types of objects that
  582. you can create, and the properties that you have to define when
  583. creating those objects.  It may appear that these object types are
  584. somehow built in to TADS.  In fact, none of these types are special;
  585. they're all defined using the TADS language.
  586.  
  587. The objects we've seen so far -- room, item, container, openable,
  588. fixeditem -- are defined in the file ADV.T.  This file is a set of
  589. object type definitions that are suitable for most games, but they're
  590. not at all special, so you can take them or leave them as you choose.
  591. You could even completely rewrite ADV.T if you want your game to
  592. behave differently.
  593.  
  594. Note that you can create objects using the types defined in ADV.T
  595. (or in your own program) very easily -- as though the types were
  596. somehow built in to TADS.  The trick that makes this possible is
  597. called "inheritance".  The TADS language allows you to define an
  598. object so that it inherits all of the properties of another object.
  599. This is what you're doing when you create an object of type room:
  600. you're telling TADS that it should create a new object exactly like
  601. the object "room" that it's already seen, except that you want to
  602. add some new properties of your own.  If you look at ADV.T, you'll
  603. see that the definition of the room object is very complex; however,
  604. you can create objects of type room without having to know very
  605. much about the room object itself -- all you need to know is what
  606. properties you need to add to the new object.
  607.  
  608. ADV.T defines many more objects than we've talked about so far.
  609. You should refer to ADV.T for complete information on the
  610. standard adventure objects, and how to use them.  Here's a brief
  611. list.
  612.  
  613.    nestedroom    -- a room within another room
  614.    chairitem     -- a chair (something the player can sit on)
  615.    beditem       -- a bed (something the player can lie down on)
  616.    thing         -- low-level item class (not normally used directly)
  617.    item          -- a simple item the player can pick up and carry
  618.    lightsource   -- something that provides light
  619.    hiddenItem    -- an object that starts off hidden within another object
  620.    hider         -- low-level hider class (not used directly)
  621.    underHider    -- an object that can have objects hidden under it
  622.    behindHider   -- an object that can have objects hidden behind it
  623.    searchHider   -- an object that can have objects hidden within it
  624.    fixeditem     -- an immovable item
  625.    readable      -- something the player can read
  626.    fooditem      -- something the player can eat
  627.    dialItem      -- something the player can turn to various values
  628.    switchItem    -- something the player can turn on and off
  629.    room          -- a location in the game
  630.    darkroom      -- a location without any lighting of its own
  631.    Actor         -- a character in the game
  632.    moveableActor -- a character that the player can pick up and carry
  633.    follower      -- a psuedo-object that can be used to follow actors
  634.    basicMe       -- a set of definitions suitable for most player actors
  635.    decoration    -- an item that serves no purpose other than decoration
  636.    buttonItem    -- something the player can push
  637.    clothingItem  -- something the player can wear
  638.    obstacle      -- something that blocks travel
  639.    doorway       -- one side of a door
  640.    lockableDoorway -- a door that can be locked
  641.    vehicle       -- an item that can be used for travel
  642.    surface       -- an item that can have objects placed upon it
  643.    container     -- an item that can have objects placed within it
  644.    openable      -- a container that can be opened and closed
  645.    qcontainer    -- a container that doesn't list its contents automatically
  646.    lockable      -- an openable that can be locked and unlocked
  647.    keyedLockable -- a lockable that needs a key to be locked and unlocked
  648.    keyItem       -- an item that can lock and unlock a keyedLockable
  649.    transparentItem -- an object whose contents are visible
  650.    basicNumObj   -- definition suitable for numObj in most games
  651.    basicStrObj   -- definition suitable for strObj in most games
  652.    deepverb      -- a verb object
  653.    travelVerb    -- a verb object for travel verbs
  654.    sysverb       -- a "system" verb
  655.    Prep          -- a preposition object
  656.  
  657. Each object in ADV.T is fully described in a comment preceding its
  658. definition.  The comments tell what properties you need to define
  659. when creating an object of each type, and how the object will behave.
  660.  
  661.  
  662. ------------------------------------------------------------------------------
  663. Methods
  664.  
  665. We mentioned earlier that a property can contain a simple value,
  666. such as a string or a number, or programming code that defines its
  667. behavior.  When a property contains code, it is called a "method".
  668. With the exception of vocabulary properties, any property can
  669. contain programming code instead of a simple value.
  670.  
  671. Programming code starts with a left brace ("{"), and ends with
  672. a matching right brace ("}").  Within the braces, you can use
  673. programming language statements that create local variables,
  674. call functions and methods, assign values to properties and
  675. variables, and control flow with loops and conditionals.  The
  676. programming code used in TADS methods looks similar to the C
  677. language, but there are some differences.
  678.  
  679. Here's an example of an object incorporating a method.  In this
  680. case, the object defines its ldesc property using a method,
  681. rather than a simple double-quoted string value, so that the
  682. property can be sensitive to the state of a window.
  683.  
  684.    attic: room
  685.       sdesc = "Attic"
  686.       ldesc =
  687.       {
  688.          "You're in a large, dusty attic.  Old cobwebs hang
  689.          from the rafters.  At the north end of the room is
  690.          a window, which is ";
  691.          if (atticWindow.isopen)
  692.             "open";
  693.          else
  694.             "closed";
  695.          ". A ladder leads down.";
  696.       }
  697.       down = hallway
  698.    ;
  699.  
  700. The ldesc property displays a message that depends on whether the
  701. window is open or closed.  For example, if the window is open, the
  702. room's long description would look like this:
  703.  
  704.    You're in a large, dusty attic.  Old cobwebs hang from the
  705.    rafters.  At the north end of the room is a window, which
  706.    is open.  A ladder leads down.
  707.  
  708.  
  709. ------------------------------------------------------------------------------
  710. Expressions
  711.  
  712. TADS expressions are entered in algebraic notation.  For example,
  713. to add two numbers, you would code an expression like this:
  714.  
  715.    3 + 4
  716.  
  717. You can use parentheses to change the order of evaluation of the
  718. parts of an expression.  For example, since multiplication has higher
  719. precedence than addition, the expression 3 + 4 * 5 evaluates to 23;
  720. however, if you write this as (3 + 4) * 5, its value is 35, because
  721. the addition is performed before the multiplication.
  722.  
  723. If you want to assign a value, you use the operator ":=" (a colon
  724. followed immediately by an equals sign, without any intervening spaces).
  725. For example, to assign the value nil to the isopen property of the
  726. object atticWindow, you'd code this:
  727.  
  728.    atticWindow.isopen := nil;
  729.  
  730. The period (or "dot") operator, ".", is used to take a property of
  731. an object.  In the example above, it specifies the isopen property of
  732. the object atticWindow.  You can use the value of a property in an
  733. expression, or assign a new value to a property, using this operator.
  734.  
  735. Here are the TADS operators, shown in the order of evaluation.
  736.  
  737.    &      Takes the "address" of a function or property.
  738.  
  739.    .      Takes a property of an object:  obj.prop evaluates property
  740.           prop of object obj.
  741.  
  742.    []     List indexing.  If var contains the list [5 4 3 2 1], then
  743.           var[2] is 4, var[4] is 2, var[5] is 1, and so on.
  744.  
  745.    ++     Increment a variable that contains a number, assigning the
  746.           incremented value back to the variable.  If var contains
  747.           5, it will contain 6 after var++ is evaluated.
  748.  
  749.    --     Decrement.
  750.  
  751.    not    Logical negation.  not true is nil, and not nil is true.
  752.  
  753.    -      Arithmetic negation (when used as a unary prefix operator).
  754.  
  755.    *      Numeric multiplication:  5 * 6 is 30.
  756.  
  757.    /      Numeric integer division:  30 / 5 is 6.  Note that any
  758.           fractional part of the division is discarded, so 5 / 2 is 2.
  759.  
  760.    +      Numeric addition:   3 + 4 is 7.
  761.           String concatenation:  'hello' + 'goodbye' yields 'hellogoodbye'.
  762.           List concatenation:  [1 2] + [3 4] yields [1 2 3 4].
  763.           List extension:  [1 2] + 3 yields [1 2 3].
  764.  
  765.    -      Numeric subtraction:  10 - 3 is 7.
  766.           List removal:  [1 2 3] - 2 yields [1 3].
  767.  
  768.    =      Equality comparison; a = b yields true if the value of a
  769.           is the same as the value of b, nil otherwise.  Note that
  770.           the types of a and b must be suitable for comparison; you
  771.           can compare two numbers, strings, lists, objects, or
  772.           truth values (true and nil); but comparing a number to a
  773.           string is meaningless, and results in a run-time error.
  774.  
  775.    <>     Inequality comparison; a <> b is true if a is not equal
  776.           to b, nil otherwise.
  777.  
  778.    >      Greater than comparison.  You can compare the magnitude
  779.           of two numbers or two strings.
  780.  
  781.    <      Less than comparison.
  782.  
  783.    >=     Greater than or equal.
  784.  
  785.    <=     Less than or equal.
  786.  
  787.    and    Logical product:  a and b is true if both a and b are true,
  788.           nil otherwise.  Note that if a is nil, b is not evaluated,
  789.           because the expression's result is nil regardless of the value
  790.           of b.
  791.  
  792.    or     Logical sum:  a or b is true if either a or b is true, or
  793.           if both are true.  Note that if a is true, b is not evaluated.
  794.  
  795.    ? :    Conditional operator:  cond ? a : b yields the value of a
  796.           if cond is true, b if cond is nil.  Note that only one of
  797.           a or b is evaluated.
  798.  
  799.    :=     Assignment.
  800.  
  801.    +=     Add and assign:  the value of the variable or property on
  802.           the left has the value of the expression on the right added
  803.           to it.  a += b is equivalent to a := a + b.
  804.  
  805.    -=     Subtract and assign.
  806.  
  807.    *=     Multiply and assign.
  808.  
  809.    /=     Divide and assign.
  810.  
  811.    ,      Conjunction:  the expression on the left of the comma is
  812.           evaluated, then the expression on the right is evaluated
  813.           and used as the value of the entire conjunction expression.
  814.           So, the value of (a, b) is b.
  815.  
  816.  
  817. ------------------------------------------------------------------------------
  818. Self
  819.  
  820. Within a method, there's a special pseudo-object called "self" that
  821. lets you determine the object whose method is being evaluated.  This
  822. may sound pretty useless, but consider a situation in which you're
  823. defining an object that inherits from another object.
  824.  
  825.    book: item
  826.       sdesc =
  827.       {
  828.         "The book is "; self.color; ". ";
  829.       }
  830.    ;
  831.  
  832.    redbook: book
  833.       color = "red"
  834.    ;
  835.  
  836.    bluebook: book
  837.       color = "blue"
  838.    ;
  839.  
  840. Here, the superclass object, book, can define a generic sdesc method
  841. which automatically adjusts to the individual subclass objects.
  842. When redbook.sdesc is evaluated, the actual sdesc code that is
  843. executed is inherited from book; however, since it is redbook.sdesc
  844. that is being evaluated, self is set to redbook, so when book.sdesc
  845. evaluated self.color, "red" is displayed.  Likewise, when bluebook.sdesc
  846. is evaluated, self is set to bluebook, so self.color displays "blue".
  847. The classes defined in ADV.T make extensive use of this mechanism
  848. to allow them to define generic attributes of the classes which
  849. automatically customize themselves to the objects you create in
  850. your game, even though the authors of ADV.T couldn't possibly
  851. have known anything about your objects beforehand.
  852.  
  853.  
  854. ------------------------------------------------------------------------------
  855. When do Methods Run?
  856.  
  857. Before we talk about how to write TADS methods in any more detail, we
  858. should look at how the TADS parser works, because it's the parser that
  859. decides what methods to call.
  860.  
  861. When the player types a command to TADS, the parser breaks the command
  862. into a series of words.  The parser then looks through its tables of
  863. vocabulary words to see what objects are associated with those words;
  864. remember that the special properties verb, noun, plural, adjective,
  865. article, and preposition associate an object with a set of vocabulary
  866. words.  Once the parser has determined which objects are involved in
  867. the command, it calls a series of methods in those objects; these
  868. methods do all the work of processing the command.  Since the methods
  869. are defined in the objects, you can change almost any aspect of the
  870. behavior of a TADS game; however, thanks to inheritance, you don't
  871. have to change anything if you don't want to -- you can use the
  872. definitions from ADV.T as they are, filling in only the necessary
  873. descriptive text and properties.
  874.  
  875. The command is associated with a set of objects; each object is
  876. classified according to its function in the command.  The objects
  877. are the actor, the verb, an optional set of direct objects, and
  878. an optional preposition and indirect object.  If the player didn't
  879. direct the command to a different character (for example:  "floyd,
  880. give me the ball"), the player-actor, Me, is assumed.
  881.  
  882. The sequence of method calls is shown below.  The actual objects
  883. making up the command are substituted for the items in <angle
  884. brackets>.  If one of the objects is not used in the command,
  885. the corresponding object parameter will be nil (for example,
  886. if there is no direct object, <dobj> will be replaced by nil).
  887.  
  888. In the list below, you'll also see something named <verb-prefix>.
  889. This is a special string that is defined in the deepverb objects;
  890. we'll discuss this below.  If the <verb-prefix> is, for example,
  891. 'Take', then the method meant by do<verb-prefix> is doTake.
  892.  
  893.    <actor> . roomCheck( <verb> )
  894.    <actor> . actorAction( <verb>, <dobj>, <prep>, <iobj> )
  895.    <actor> . location . roomAction( <actor>, <verb>, <dobj>, <prep>, <iobj> )
  896.  
  897.    If an indirect object was specified:
  898.       <dobj> . verDo<verb-prefix>( <actor>, <iobj> )
  899.       If no output resulted from verDo<verb-prefix>:
  900.          <iobj> . verIo<verb-prefix>( <actor> )
  901.          If no output resulted from verIo<verb-prefix>:
  902.             <iobj> . io<verb-prefix>( <actor>, <dobj> )
  903.    Else if a direct object was specified:
  904.       <dobj> . verDo<verb-prefix>( <actor> )
  905.       If no output resulted from verDo<verb-prefix>:
  906.          <dobj> . do<verb-prefix>( <actor> )
  907.    Else:
  908.       <verb> . action( <actor> )
  909.  
  910.    Run each daemon that is currently active
  911.    Run and remove each fuse that has burned down to zero turns
  912.  
  913. The <verb-prefix> is read from the verb object when a direct or
  914. indirect object is present.  The <verb-prefix> is a string specified
  915. by the property doAction when only a direct object is present, or
  916. from the appropriate ioAction when both a direct and an indirect object
  917. are present.  For example, consider this verb object:
  918.  
  919.    takeVerb: deepverb
  920.       verb = 'take'
  921.       sdesc = "take"
  922.       doAction = 'Take'
  923.       ioAction(outofPrep) = 'TakeOut'
  924.       ioAction(awayPrep) = 'TakeAway'
  925.    ;
  926.  
  927. If the command is "take ball", only a direct object is present, so
  928. the doAction property is used, and hence the <verb-prefix> is 'Take'.
  929. This means that the methods called in the direct object will be
  930. verDoTake and doTake.  In this case, the sequence of methods that
  931. the parser calls would be:
  932.  
  933.    Me.roomCheck(takeVerb)
  934.    Me.actorAction(takeVerb, ball, nil, nil)
  935.    Me.location.roomAction(Me, takeVerb, ball, nil, nil)
  936.    ball.verDoTake(Me)
  937.    if no ouput resulted from verDoTake:
  938.       ball.doTake(Me)
  939.  
  940. If the command is "take ball out of box", the ioAction property
  941. matching the preposition "out of" is used; this is 'TakeOut'.  So,
  942. the properties called in the objects are verDoTakeOut, verIoTakeOut,
  943. and ioTakeOut.  In this case, the sequence of methods called by
  944. the parser would be:
  945.  
  946.    Me.roomCheck(takeVerb)
  947.    Me.actorAction(takeVerb, ball, box, outofPrep)
  948.    Me.location.roomAction(Me, takeVerb, ball, box, outofPrep)
  949.    ball.verDoTakeOut(Me, box)
  950.    If no output resulted from verDoTakeOut:
  951.       box.verIoTakeOut(Me)
  952.       If no output resulted from verIoTakeOut:
  953.          box.ioTakeOut(Me, ball)
  954.  
  955. This sequence may look terribly complicated, but generally you won't
  956. have to customize or even think about very much of it.  In almost
  957. every case, you'll be able to achieve the effect you want by customizing
  958. the verDo<prefix>, do<prefix>, verIo<prefix>, and io<prefix> methods.
  959.  
  960. Note that the verDo<prefix> and verIo<prefix> methods are intended
  961. to be used to verify that the object can be used in this command,
  962. and the do<prefix> and io<prefix> methods are supposed to actually
  963. carry out the command.  The way this works is that the verDo<prefix>
  964. and verIo<prefix> methods should display an error message if the
  965. object cannot be used for this command, and should do nothing at
  966. all if the object is usable.  This may sound like a strange way
  967. to decide whether the object is valid, but it makes it extremely
  968. convenient to write these methods -- all you have to do is display
  969. an error message if appropriate during verification.
  970.  
  971.  
  972. ------------------------------------------------------------------------------
  973. Programming Statements
  974.  
  975. Within a method, or within a function, you can use a number of
  976. statements that control execution.
  977.  
  978.  
  979. local <variable-list> ;
  980.  
  981.    This statement can be used only at the very start of a block
  982.    of code (that is, immediately following an open brace).  The
  983.    "local" statement defines a list of variables that are private
  984.    to the block of code; these variables cannot be used outside
  985.    of the block.  Variable names follow the same rules as other
  986.    identifiers, such as object and property names:  they must
  987.    start with a letter, and consist of letters, numbers, and
  988.    underscores.
  989.  
  990.    Example:
  991.  
  992.        ldesc =
  993.     {
  994.        local cnt, loc;
  995.  
  996.            cnt := 0;
  997.            loc := nil;
  998.     }
  999.  
  1000.  
  1001. return <expression> ;
  1002.  
  1003.    Return to the caller.  The <expression> is evaluated, and the result
  1004.    is supplied to the caller as the value of the method or function.
  1005.    Control is returned to the caller at the point immediately following
  1006.    the call to the current method or function; no further statements
  1007.    in the current method or function are executed.
  1008.  
  1009. return ;
  1010.  
  1011.    Return to the caller without providing a value.
  1012.  
  1013. if ( <expression> ) <statement1> else <statement2>
  1014.  
  1015.    Evaluate the <expression>; if the value is not nil or 0, execute
  1016.    <statement1>.  Otherwise, execute <statement2>.  Note that the
  1017.    entire "else" clause is optional; if it is not provided, and the
  1018.    value of <expression> is nil or 0, execution resumes following
  1019.    <statement1>.
  1020.  
  1021.    Note that <statement1> and <statement2> can either be a single
  1022.    statement, or can be a series of statements enclosed in braces.
  1023.  
  1024.    Example:
  1025.  
  1026.        if (torch.islit)
  1027.         {
  1028.            "You suddenly realize that the odor was coal gas,
  1029.             and that you're carrying a burning torch.  You
  1030.             try to retreat, but it's too late; the torch
  1031.             ignites the gas, resulting in a terrible explosion.";
  1032.             die();
  1033.         }
  1034.         else
  1035.             "You realize that the odor was coal gas.
  1036.              Fortunately, there's no open flame here.";
  1037.  
  1038.  
  1039. switch ( <expression> )
  1040. {
  1041. case <constant1>:   <statements1>; 
  1042. case <constant2>:   <statements2>;
  1043. default:  <statements3>;
  1044. }
  1045.  
  1046.    This statement allows you to choose a number of execution
  1047.    paths, based on the value of an expression.  The <expression>
  1048.    is evaluated, then compared to the various constants at the case
  1049.    labels.  If a case label matches the value of the expression,
  1050.    execution resumes at the statement following that case label.
  1051.    If no case label matches the value, and a default label is
  1052.    present, execution resumes following the default.  The default
  1053.    label is optional.
  1054.  
  1055.    Note that execution is not interrupted by hitting another
  1056.    case label, but just continues into the statements following it.
  1057.    Note also that a case label need not have any statements at all
  1058.    following it.  If you want to exit the switch statement, you
  1059.    must explicitly code a break statement; this causes execution
  1060.    to resume following the end of the switch statement.
  1061.  
  1062.    Example:
  1063.  
  1064.        switch(x)
  1065.         {
  1066.     case 1:
  1067.     case 2:
  1068.        "x is 1 or 2";
  1069.        break;
  1070.  
  1071.     case 3:
  1072.        "x is 3";
  1073.            /* note the lack of a break, so we fall through to next case */
  1074.  
  1075.     case 4:
  1076.        "x is 3 or 4";
  1077.        break;
  1078.  
  1079.     default:
  1080.        "x is 5 or more";
  1081.         }
  1082.  
  1083.  
  1084. while ( <expression> ) <statement>
  1085.  
  1086.    Execute <statement> repeatedly as long as the value <expression>
  1087.    is not nil or 0.  The <expression> is evaluated before each
  1088.    execution of <statement>, so if the value of <expression> is
  1089.    nil or 0 before the first execution of the loop, the <statement>
  1090.    is not executed at all.  As with the if statement, the <statement>
  1091.    can be either a single statement, or a block of statements enclosed
  1092.    in braces.
  1093.  
  1094.    Example:
  1095.  
  1096.        while (cnt < length(lst))
  1097.         {
  1098.        "The next item is: "; say(lst[cnt]); "\n";
  1099.            ++cnt;
  1100.         }
  1101.  
  1102. do <statement> while ( <expression> );
  1103.  
  1104.    This statement is similar to the while statement, but evaluates
  1105.    <expression> after each iteration of the loop.  Thus, the <statement>
  1106.    is always executed at least once, since the <expression> is not
  1107.    tested for the first time until after the first iteration of the
  1108.    loop.
  1109.  
  1110.    Example:
  1111.  
  1112.        do
  1113.         {
  1114.        "cnt = "; say(cnt); "\n";
  1115.            --cnt;
  1116.     } while (cnt > 0);
  1117.  
  1118. for ( <init-expr> ; <cond-expr> ; <reinit-expr> ) <statement>
  1119.  
  1120.    This is a more general form of loop.  First, the <init-expr> is
  1121.    evaluated; this is done only once, before the loop starts iterating.
  1122.    For each iteration of the loop, TADS first evaluates the <cond-expr>.
  1123.    If it is nil or 0, the loop terminates; otherwise, <statement> is
  1124.    executed.  Finally, <reinit-expr> is evaluted.  Note that any
  1125.    of the expressions may be omitted; if the <cond-expr> is not
  1126.    present, it is as though the expression were always true.
  1127.  
  1128.    The for statement is often more convenient to code, but it
  1129.    is always possible to write an equivalent loop using the
  1130.    while statement.
  1131.  
  1132.    Example:
  1133.  
  1134.        for (cnt := 1 ; cnt < length(lst) ; ++cnt)
  1135.         {
  1136.            "the next element is: "; say(lst[cnt]); "\n";
  1137.         }
  1138.  
  1139. break;
  1140.  
  1141.    Exits from a while, do-while, or for loop, or from a switch
  1142.    statement.  Control immediately resumes following the end of
  1143.    the loop or switch.  The break statement is useful when the
  1144.    condition for exiting a loop is most conveniently calculated
  1145.    somewhere in the middle of the loop's processing.
  1146.  
  1147. continue;
  1148.  
  1149.    Returns to the beginning of a while, do-while, or for loop.
  1150.    The statements following the continue statement are skipped
  1151.    for this iteration of the loop.  In a for loop, the <reinit-expr>
  1152.    is evaluated after a continue statement.
  1153.  
  1154. pass <property-name>;
  1155.  
  1156.    When a method is executing, and the method has overridden a
  1157.    method in a superclass object, the pass statement will cause
  1158.    control to be passed to the superclass method that the current
  1159.    method overrides.  Note that execution never returns to the
  1160.    current method after a pass statement.  Note also that the
  1161.    <property-name> must match the name of the current property.
  1162.  
  1163. exit;
  1164.  
  1165.    Terminate all processing for the current player command,
  1166.    and skip everything up to the daemons and fuses.  This
  1167.    statement is used when the current method has done everything
  1168.    necessary to finish the command, and no further processing
  1169.    is desirable.
  1170.  
  1171. abort;
  1172.  
  1173.    Terminate all processing for the current player command,
  1174.    skip the daemons and fuses, and go on to the next command.
  1175.    This statement is normally used by "system" verbs, such as
  1176.    "save" and "restore", to prevent any time from passing (time
  1177.    in the game is handled by the fuses and daemons).
  1178.  
  1179. askdo;
  1180.  
  1181.    Abort the current command, and ask the player to specify a
  1182.    direct object.
  1183.  
  1184. askio( <prep-object> );
  1185.  
  1186.    Abort the current command, supply <prep-object> as the preposition
  1187.    for the command, and ask the player to specify an indirect object.
  1188.  
  1189.  
  1190. ------------------------------------------------------------------------------
  1191. Built-in Functions
  1192.  
  1193. TADS has a number of built-in functions that you can call from
  1194. your game program.  Some of these functions simply provide useful
  1195. utility functions, while others affect execution of the game.
  1196. A brief description of each function is shown below.
  1197.  
  1198. askfile(prompt) - asks the player for a filename; "prompt" is a
  1199. string (single-quoted) that specifies a prompt to display to the
  1200. player.  Where appropriate, the standard system file selector is
  1201. used to ask the player for the file.
  1202.  
  1203. caps() - forces the next character displayed to be capitalized.
  1204.  
  1205. car(list) - returns the first element of a list.  For
  1206. example:  car([1 2 3]) returns 1.
  1207.  
  1208. cdr(list) - returns a list with its first element removed.  For
  1209. example:  cdr([1 2 3]) returns [2 3].
  1210.  
  1211. cvtnum(str) - converts a (single-quoted) string containing the
  1212. textual representation of a number to a numeric value.  For
  1213. example, cvtnum('1234') returns 1234.
  1214.  
  1215. cvtstr(num) - converts a number to a string containing a textual
  1216. representation of the number.  For example, cvtstr(100) returns '100'.
  1217.  
  1218. datatype(val) - returns the datatype of the "val" (after evaluating
  1219. the value).  The return values are:
  1220.  
  1221.    1 - number
  1222.    2 - object
  1223.    3 - string
  1224.    5 - nil
  1225.    7 - list
  1226.    8 - true
  1227.    10 - function pointer
  1228.    13 - property pointer
  1229.  
  1230. defined(obj, &prop) - returns true if the object "obj" defines or
  1231. inherits property "prop", nil otherwise.
  1232.  
  1233. find(value, target) - returns the offset of "target" within "value".
  1234. If "value" is a list, this function returns the index of the "target"
  1235. within the list, or nil if it does not occur in the list.  For
  1236. example, find([5 4 3], 4) returns 2.  If "value" is a string,
  1237. this function returns the offset of the substring "target", or
  1238. nil if there is no such substring.  For example, find('abcdef', 'cde')
  1239. returns 3.
  1240.  
  1241. firstobj() - begins a loop over all non-class objects in a game.
  1242. Returns an object.  See nextobj(obj).
  1243.  
  1244. firstobj(cls) - begins a loop over all non-class objects with
  1245. superclass "cls".  See nextobj(obj, cls).
  1246.  
  1247. getarg(num) - return the value of argument number "num" to the current
  1248. method or function.
  1249.  
  1250. incturn() - increments the turn counter, which moves all fuses
  1251. one turn closer to firing.  Normally, this function is called
  1252. by a daemon function once per turn.
  1253.  
  1254. input() - allows the user to enter a line of text, and returns
  1255. the value as a string.
  1256.  
  1257. isclass(obj, cls) - returns true if "obj" inherits from superclass
  1258. "cls", nil otherwise.
  1259.  
  1260. length(val) - returns the number of characters in a string, or
  1261. the number of elements in a list.
  1262.  
  1263. logging(val) - if "val" is a string, creates the file named by
  1264. the string, and logs all text displayed on the screen to the file.
  1265. If "val" is nil, closes the current log file and stops logging.
  1266.  
  1267. lower(str) - returns a string consisting of all of the characters
  1268. of "str" converted to lower case.
  1269.  
  1270. nextobj(obj) - returns the object following "obj", in an arbitrary
  1271. order, or nil if the last object has been reached.  Every non-class
  1272. object in the game will be returned exactly once by a loop such as
  1273. this:
  1274.  
  1275.    local obj;
  1276.    for (obj := firstobj() ; obj ; obj := nextobj(obj)) /* ... */;
  1277.  
  1278. nextobj(obj, cls) - returns the next object following "obj"
  1279. with superclass "cls", or nil if the last such object has been
  1280. reached.  Every non-class object in the game with superclass cls
  1281. will be returned by a loop such as this:
  1282.  
  1283.    local obj;
  1284.    for (obj := firstobj(cls) ; obj ; obj := nextobj(obj, cls)) /* ... */;
  1285.  
  1286. notify(obj, &prop, turns) - establish a notifier.  The property "prop"
  1287. of object "obj" (i.e., obj.prop) is called once after the number of turns
  1288. specified by "turns" has elapsed.  If "turns" is zero, obj.prop is called
  1289. after every turn.
  1290.  
  1291. proptype(obj, &prop) - returns the type of property "prop" in object
  1292. "obj", without evaluating the property.  If the property contains
  1293. method code, the code is not called by this function, so the return
  1294. type of the property cannot be determined; instead, proptype simply
  1295. returns 6, to indicate that the property contains method code.  The
  1296. return values are:
  1297.  
  1298.    1 - number
  1299.    2 - object
  1300.    3 - single-quoted string
  1301.    5 - nil
  1302.    6 - code
  1303.    7 - list
  1304.    8 - true
  1305.    9 - double-quoted string
  1306.    10 - function pointer
  1307.    13 - property pointer
  1308.  
  1309. quit() - end the game.
  1310.  
  1311. rand(lim) - return a random number from 0 to "lim", inclusive.
  1312.  
  1313. randomize() - seed the random number generator with a value chosen
  1314. by the system.  This function is called only once, at the beginning
  1315. of the game, to choose a random number seed.  If this function is
  1316. not called, the sequence of numbers returned by rand() is the same
  1317. each time the game is played.
  1318.  
  1319. remdaemon(function, value) - remove a daemon previously set by
  1320. the setdaemon() built-in function.  The daemon set with the same
  1321. values of "function" and "value" will be removed; if no such daemon
  1322. is found, a run-time error is reported.
  1323.  
  1324. remfuse(function, value) - remove a fuse previously set
  1325. by the setfuse() built-in function.
  1326.  
  1327. restart() - start the game over from the beginning.
  1328.  
  1329. restore(filename) - restore the game position stored in the file
  1330. named by the string "filename".
  1331.  
  1332. save(filename) - save the current game position to the file
  1333. named by the string "filename".
  1334.  
  1335. say(value) - display the value, which can be a single-quoted string
  1336. or a number.
  1337.  
  1338. setdaemon(function, value) - set a daemon.  "function" will be
  1339. called once after every turn, with "value" as its argument.  "value"
  1340. is an arbitrary value that is provided to allow you to pass
  1341. any information to the daemon that it may need.  The daemon
  1342. function should be defined prior to its use in setdaemon().
  1343.  
  1344. setfuse(function, time, value) - set a fuse.  "function" will be
  1345. called after the number of turns specified in "time" has elapsed.
  1346. "value" is an arbitrary value that is passed to the function as
  1347. its argument; you can specify any value that you find useful here.
  1348.  
  1349. setit(obj) - set "it" to the specified object.  This changes the
  1350. object that the player refers to with the word "it".
  1351.  
  1352. setscore(score, turns) - set the score displayed on the status line.
  1353. "score" and "turns" are numbers.
  1354.  
  1355. setscore(str) - specify an arbitrary single-quoted string that will
  1356. be displayed on the status line in place of the normal score/turns
  1357. indicator.
  1358.  
  1359. substr(str, ofs, len) - returns the substring of "str" starting
  1360. at offset "ofs" and going for "len" characters.  For example,
  1361. substr('abcdef', 3, 2) returns 'cd'.
  1362.  
  1363. undo() - undoes one turn.
  1364.  
  1365. unnotify(obj, &prop) - remove the notifier previously set on obj.prop.
  1366. If there is no such notifier, a run-time error is reported.
  1367.  
  1368. upper(str) - returns the string "str" with its characters converted
  1369. to upper-case.
  1370.  
  1371. yorn() - waits for the player to answer YES or NO.  Returns
  1372. 1 if the player typed YES, 0 if the player typed NO, and -1 if
  1373. the player typed anything else.  Note that only the first
  1374. character of the player's response is checked, and the response
  1375. can be upper- or lower-case.
  1376.  
  1377.  
  1378. ------------------------------------------------------------------------------
  1379. Where to go from Here
  1380.  
  1381. There's a lot more to TADS than we are able to describe here.
  1382. To learn more, you can start by looking at the example game
  1383. "Ditch Day Drifter" that we've included with the TADS software
  1384. distribution.  While this game doesn't do everything that you can
  1385. do with TADS (in fact, since TADS is so flexible, it doesn't even
  1386. really scratch the surface), it does contain examples of many
  1387. common adventure game situations that may help you in designing
  1388. your own game.
  1389.  
  1390. For full details on TADS, you should obtain the TADS Author's
  1391. Manual.  This is freely available in electronic format; you should
  1392. be able to find it the same place you found TADS.  The Author's
  1393. Manual includes:
  1394.  
  1395.   - An overview of the concepts used in the TADS programming
  1396.     language.
  1397.  
  1398.   - A detailed description of the TADS programming language,
  1399.     including how to define functions and objects, how to write
  1400.     procedural code, and how to write expressions.
  1401.  
  1402.   - How to use the TADS Debugger, a powerful source-level
  1403.     debugger for TADS programs.
  1404.  
  1405.   - Descriptions of all of the built-in functions.
  1406.  
  1407.   - Descriptions of the objects in ADV.T, and how to use them.
  1408.  
  1409.   - An introduction to object-oriented programming.
  1410.  
  1411.   - How the player command parser works:  how it reads commands,
  1412.     disambiguates nouns, and calls your program to carry out
  1413.     commands.
  1414.  
  1415.   - Descriptions of the special properties that the system
  1416.     calls in your game objects.
  1417.  
  1418.   - Descriptions of the special objects that your game
  1419.     program must provide.
  1420.  
  1421.   - Explanations of system error messages.
  1422.  
  1423.   - Details on how to write and use external functions written
  1424.     in a language such as C.
  1425.  
  1426.   - How to use the compiler and run-time system.
  1427.  
  1428.   - Advice on the what to do (and what not to do) when designing
  1429.     a game to make your game more fun to play.
  1430.  
  1431.  
  1432. In addition, the TADS Author's Manual contains a large number
  1433. of detailed examples that show you how to write your own games.
  1434. The chapter "Getting Started with TADS" shows you how to design
  1435. a game, and how to turn your design into a TADS program.  The
  1436. chapter "Advanced TADS Techniques" provides 40 pages of examples
  1437. with full explanations, showing how to implement a wide variety
  1438. of game situations, such as:
  1439.  
  1440.   - Creating your own verbs
  1441.  
  1442.   - Using doors and other obstacles
  1443.  
  1444.   - Creating vehicles
  1445.  
  1446.   - Hiding objects
  1447.  
  1448.   - Creating non-player characters
  1449.  
  1450.  
  1451.  
  1452. ABOUT HIGH ENERGY SOFTWARE
  1453. --------------------------
  1454.  
  1455. High Energy Software formerly distributed TADS as a shareware system,
  1456. but is no longer in business.  Mike Roberts, the developer of TADS,
  1457. is now maintaining and distributing the system as freeware.  We have
  1458. made an effort to remove references from these files to High Energy
  1459. Software and its former telephone and other contact information,
  1460. since all of those numbers and addresses are no longer in service.
  1461. If we inadvertantly left any such references intact, please disregard
  1462. them, since they're oversights.
  1463.  
  1464.